package com.aoip.telemetry.telemetry.configureui.business.pipeline.sthandle.service.impl;

import com.aoip.telemetry.telemetry.configureui.business.pipeline.handle.mapper.PipelineHandleMapper;
import com.aoip.telemetry.telemetry.configureui.business.pipeline.sthandle.mapper.RelStHandleMapper;
import com.aoip.telemetry.telemetry.configureui.business.pipeline.sthandle.mapper.RelStHandleStMapper;
import com.aoip.telemetry.telemetry.configureui.business.pipeline.sthandle.service.RelStHandleService;
import com.aoip.telemetry.telemetry.core.redis.RedisCache;
import com.aoip.telemetry.telemetry.entity.enums.CacheKeyEnum;
import com.aoip.telemetry.telemetry.entity.equipment.StInfoConfigEntity;
import com.aoip.telemetry.telemetry.entity.pipeline.PipelineHandleEntity;
import com.aoip.telemetry.telemetry.entity.pipeline.RelStHandleEntity;
import com.aoip.telemetry.telemetry.entity.pipeline.RelStHandleStEntity;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author chenbai
 * @version 1.0
 * @date 2022/2/14 11:19
 */
@Service
public final class RelStHandleServiceImpl implements RelStHandleService {
    @Resource
    private PipelineHandleMapper pipelineHandleMapper;
    @Resource
    private RelStHandleMapper mapper;
    @Resource
    private RelStHandleStMapper stMapper;
    @Resource
    private RedisCache redisCache;

    @Override
    public List<RelStHandleEntity> list(RelStHandleEntity entity) {
        return mapper.list(entity);
    }

    @Override
    public RelStHandleEntity relStHandle(String id) {
        RelStHandleEntity entity = mapper.selectById(id);
        QueryWrapper<RelStHandleStEntity> queryWrapper = new QueryWrapper<>();
        String relStHandleId = entity.getId();
        queryWrapper.eq("rel_st_handle_id", relStHandleId);
        List<RelStHandleStEntity> stEntityList = stMapper.selectList(queryWrapper);
        entity.setRelStHandleStEntityList(stEntityList);
        StringBuilder sb = new StringBuilder();
        stEntityList.forEach(item -> sb.append(item.getStCode()).append(","));
        String s = sb.toString();
        if (s.endsWith(",")) {
            s = s.substring(0, s.length() - 1);
        }
        entity.setStCode(s);
        return entity;
    }

    @Override
    public int insert(RelStHandleEntity entity) {
        String stCode = entity.getStCode();
        int insert = mapper.insert(entity);
        if (StringUtils.hasText(stCode)) {
            List<RelStHandleStEntity> stList = new ArrayList<>();
            if (stCode.contains(",")) {
                String[] stCodes = stCode.split(",");
                for (String code : stCodes) {
                    stList.add(new RelStHandleStEntity(entity.getId(), code));
                    List<RelStHandleEntity> handleList = getHandleListByStCode(code);
                    initSingleStCodeHandleCache(code, handleList);
                }
            } else {
                stList.add(new RelStHandleStEntity(entity.getId(), stCode));
                List<RelStHandleEntity> handleList = getHandleListByStCode(stCode);
                initSingleStCodeHandleCache(stCode, handleList);
            }
            stList.forEach(item -> stMapper.insert(item));
        }
        return insert;
    }

    @Override
    public int update(RelStHandleEntity entity) {
        QueryWrapper<RelStHandleStEntity> queryWrapper = new QueryWrapper<>();
        String relStHandleId = entity.getId();
        queryWrapper.eq("rel_st_handle_id", relStHandleId);
        int i = mapper.updateById(entity);
        List<RelStHandleStEntity> relStHandleStEntityList = stMapper.selectList(queryWrapper);
        String stCode = entity.getStCode();
        if (StringUtils.hasText(stCode)) {
            Set<String> codeSet = new HashSet<>();
            Set<String> insertCodeSet = new HashSet<>();
            if (stCode.contains(",")) {
                String[] stCodes = stCode.split(",");
                List<String> strings = Arrays.asList(stCodes);
                insertCodeSet.addAll(strings);
                codeSet.addAll(strings);
            } else {
                insertCodeSet.add(stCode);
                codeSet.add(stCode);
            }
            relStHandleStEntityList.forEach(item -> {
                String code = item.getStCode();
                codeSet.add(code);
                if (insertCodeSet.contains(code)) {
                    insertCodeSet.remove(code);
                } else {
                    stMapper.deleteById(item.getId());
                }
            });
            insertCodeSet.forEach(code -> {
                RelStHandleStEntity stEntity = new RelStHandleStEntity();
                stEntity.setRelStHandleId(relStHandleId);
                stEntity.setStCode(code);
                stMapper.insert(stEntity);
            });
            for (String code : codeSet) {
                List<RelStHandleEntity> handleList = getHandleListByStCode(code);
                initSingleStCodeHandleCache(code, handleList);
            }
        } else {
            if (relStHandleStEntityList != null && relStHandleStEntityList.size() > 0) {
                stMapper.delete(queryWrapper);
                for (RelStHandleStEntity stEntity : relStHandleStEntityList) {
                    String code = stEntity.getStCode();
                    List<RelStHandleEntity> handleList = getHandleListByStCode(code);
                    initSingleStCodeHandleCache(code, handleList);
                }
            }
        }
        return i;
    }

    @Override
    public void delete(long[] ids) {
        for (long id : ids) {
            QueryWrapper<RelStHandleStEntity> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("rel_st_handle_id", id);
            mapper.deleteById(id);
            stMapper.delete(queryWrapper);
            List<RelStHandleStEntity> stEntities = stMapper.selectList(queryWrapper);
            for (RelStHandleStEntity entity : stEntities) {
                String stCode = entity.getStCode();
                List<RelStHandleEntity> handleList = getHandleListByStCode(stCode);
                initSingleStCodeHandleCache(stCode, handleList);
                redisCache.deleteObject(CacheKeyEnum.REL_ST_PIPELINE_HANDLE_ST + ":" + stCode);
            }
        }
    }

    @Override
    public int initCache() {
        QueryWrapper<RelStHandleStEntity> queryWrapper = new QueryWrapper<>();
        List<RelStHandleStEntity> relStHandleStList = stMapper.selectList(queryWrapper);
        Set<String> stCodeSet = new HashSet<>();
        for (RelStHandleStEntity stEntity : relStHandleStList) {
            stCodeSet.add(stEntity.getStCode());
        }
        for (String code : stCodeSet) {
            List<RelStHandleEntity> handleList = getHandleListByStCode(code);
            initSingleStCodeHandleCache(code, handleList);
        }
        return stCodeSet.size();
    }

    @Override
    public List<RelStHandleEntity> getHandleListByStCode(String stCode) {
        QueryWrapper<RelStHandleStEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("st_code", stCode);
        List<RelStHandleStEntity> relStHandleStList = stMapper.selectList(queryWrapper);
        List<String> relStHandleId = new ArrayList<>();
        relStHandleStList.forEach(item -> relStHandleId.add(item.getRelStHandleId()));
        if (relStHandleId.size() < 1) {
            return new ArrayList<>();
        }
        List<RelStHandleEntity> stHandleEntityList = mapper.selectBatchIds(relStHandleId);
        stHandleEntityList.forEach(item->{
            PipelineHandleEntity pipelineHandle = pipelineHandleMapper.selectById(item.getHandleId());
            item.setPipelineHandleEntity(pipelineHandle);
        });
        return stHandleEntityList;
    }

    private void initSingleStCodeHandleCache(String stCode, List<RelStHandleEntity> list) {
        redisCache.deleteObject(CacheKeyEnum.REL_ST_PIPELINE_HANDLE_ST + ":" + stCode);
        if (list.size() > 0) {
            List<RelStHandleEntity> collect = list.stream()
                    .sorted(Comparator.comparingInt(x -> x.getStrategyOrder() * Integer.valueOf(x.getStrategyType())))
                    .collect(Collectors.toList());
            redisCache.setCacheList(CacheKeyEnum.REL_ST_PIPELINE_HANDLE_ST + ":" + stCode, collect);
        }
    }

    @Override
    public List<StInfoConfigEntity> getHandleListByHandleId(String handleId) {
        RelStHandleEntity entity = new RelStHandleEntity();
        entity.setHandleId(handleId);
        List<RelStHandleEntity> stList = list(entity);
        for (RelStHandleEntity handleEntity : stList) {
            StInfoConfigEntity stInfoConfigEntity = new StInfoConfigEntity();
//            stInfoConfigEntity.set;
        }
        return null;
    }

}
